#define MECHPURCHASESCREEN_CPP
/*************************************************************************************************\
MechPurchaseScreen.cpp			: Implementation of the MechPurchaseScreen component.
//---------------------------------------------------------------------------//
// Copyright (C) Microsoft Corporation. All rights reserved.                 //
//===========================================================================//
\*************************************************************************************************/

#include "MechPurchaseScreen.h"
#include "mcLib.h"
#include "LogisticsData.h"
#include "MechBayScreen.h"
#include "gamesound.h"
#include "..\resource.h"
#include "SimpleCamera.h"
#include "AttributeMeter.h"
#include "Chatwindow.h"
#include "Multplyr.h"

MechPurchaseScreen* MechPurchaseScreen::s_instance = NULL;

#define INVENTORY_ID 88
#define VARIANT_ID	89


//-------------------------------------------------------------------------------------------------

MechPurchaseScreen::MechPurchaseScreen(  ) 
: inventoryListBox( 1, 0 ), variantListBox( 0, 0 )
{
	status = RUNNING;
	gosASSERT( !s_instance );
	s_instance = this;
	acceptPressed = 0;
	pDragMech = NULL;
	dragStartLeft = 0;
	helpTextArrayID = 4; 
	inventoryListBox.setID( INVENTORY_ID );
	variantListBox.setID( VARIANT_ID );

	countDownTime = .5;
	curCount = 0.0;
	previousAmount = 0;

	oldCBillsAmount  =0;

	flashTime = 0.f;
}

//-------------------------------------------------------------------------------------------------

MechPurchaseScreen::~MechPurchaseScreen()
{
	s_instance = NULL;

	variantListBox.destroy();
	inventoryListBox.destroy();
}


//-------------------------------------------------------------------------------------------------

int MechPurchaseScreen::init( FitIniFile& file )
{
	MechListBox::init();

	mechDisplay.init();

	LogisticsScreen::init( file, "Static", "Text", "Rect", "Button" );

	((aObject*)&inventoryListBox)->init( rects[0].left(), rects[0].top(),
		rects[0].width(), rects[0].height() );

	inventoryListBox.setScrollBarOrange();

	((aObject*)&variantListBox)->init( rects[1].left(), rects[1].top(),
		rects[1].width(), rects[1].height() );

	variantListBox.setScrollBarOrange();


	for ( int i= 0; i < buttonCount; i++ )
		buttons[i].setMessageOnRelease();


	return NO_ERR;
}
//-------------------------------------------------------------------------------------------------

void MechPurchaseScreen::update()
{

	
	if ( !MPlayer || !ChatWindow::instance()->pointInside(userInput->getMouseX(), userInput->getMouseY()) )
		LogisticsScreen::update();
	

	// update CBills

	int amount = LogisticsData::instance->getCBills();
	long color = 0xff005392;
	if ( amount != oldCBillsAmount )
	{
		previousAmount = oldCBillsAmount - amount;
		curCount = .00001f;
		oldCBillsAmount = amount;
		if ( previousAmount < 0 )
			soundSystem->playDigitalSample( WINDOW_OPEN );
		else
			soundSystem->playDigitalSample( WINDOW_CLOSE );
	}
	if ( curCount && curCount + frameLength < countDownTime  )
	{
		curCount += frameLength;
		float curAmount = previousAmount - (curCount/countDownTime * previousAmount); 
		amount += curAmount;

		color = 0xffc8e100;
		if ( curAmount > 0 )
			color = 0xffa21600;
	}
	else if ( flashTime )
	{
		flashTime += frameLength;
		if ( flashTime < .125
			|| ( flashTime > .25 && flashTime < .3875 )
			|| ( flashTime > .5 && flashTime < .6625 ) )
		{
			color = 0xff000000;
		}
		else if ( flashTime > .75 )
		{
			flashTime = 0;
		}
		else
		{
			color = 0xffff0000;			
		}
	}
	

	char tmp[64];
	sprintf( tmp, "%ld ", amount);
	textObjects[1].setText( tmp );
	textObjects[1].setColor( color );

	int oldSell = inventoryListBox.GetSelectedItem();
	inventoryListBox.update();
	int newSell = inventoryListBox.GetSelectedItem();
	if ( oldSell != newSell && newSell != -1 )
	{
		variantListBox.SelectItem( -1 );
	}

	oldSell = variantListBox.GetSelectedItem();
	variantListBox.update();
	newSell = variantListBox.GetSelectedItem();

	if ( oldSell != newSell  && newSell != -1 )
	{
		inventoryListBox.SelectItem( -1 );
	}

	variantListBox.disableItemsThatCostMoreThanRP();

	LogisticsMech* pCurSell = inventoryListBox.getCurrentMech();
	LogisticsMech* pCurBuy = variantListBox.getCurrentMech();

	// disable the sell button
	buttons[2].disable( pCurSell ? 0 : 1);

	if ( pCurBuy )
	{
		if ( pCurBuy->getCost() > LogisticsData::instance->getCBills() )
		{
			pCurBuy = NULL;
		}

		setMech( pCurBuy );
		
	}
	else if ( pCurSell )
		setMech( pCurSell );

	buttons[1].disable( pCurBuy ? 0 : 1 );
	if ( !pCurBuy &&
		userInput->isLeftClick() && buttons[1].pointInside( userInput->getMouseX(), userInput->getMouseY() ) )
	{
		if ( !flashTime )
			flashTime = .0001f;
	}

	// drag and drop
	// update drag and drop
	if ( pDragMech )
	{
		dragIcon.moveTo( userInput->getMouseX() - dragIcon.width() / 2, 
			userInput->getMouseY() - dragIcon.height() / 2 );

		if ( userInput->leftMouseReleased(  ) )
		{
			endDrag();	
		}

	}

	mechDisplay.update();

	inventoryListBox.enableAllItems();

	if ( MPlayer && ChatWindow::instance() )
		ChatWindow::instance()->update();

}

//-------------------------------------------------------------------------------------------------

void MechPurchaseScreen::render( int xOffset, int yOffset )
{

	if ( !xOffset && !yOffset )
	{
		if ( !MPlayer && !LogisticsData::instance->isSingleMission() && LogisticsData::instance->newMechsAvailable() )
		{
			soundSystem->playBettySample( BETTY_NEW_MECHS );
			LogisticsData::instance->setNewMechsAcknowledged();
		}
	}

	inventoryListBox.move( xOffset, yOffset);
	inventoryListBox.render();
	inventoryListBox.move( -xOffset, -yOffset );

	variantListBox.move(xOffset, yOffset);
	variantListBox.render();
	variantListBox.move(-xOffset, -yOffset);	

	mechDisplay.render( xOffset, yOffset );

	LogisticsScreen::render( xOffset, yOffset );

	if ( pDragMech )
		dragIcon.render();

	
	if ( MPlayer && ChatWindow::instance() )
		ChatWindow::instance()->render(xOffset, yOffset);



}

//-------------------------------------------------------------------------------------------------

void MechPurchaseScreen::begin()
{

	variantListBox.removeAllItems(true);
	inventoryListBox.removeAllItems(true);
	// initialize both the inventory and icon lists
	EList< LogisticsMech*, LogisticsMech* > mechList;
	LogisticsData::instance->getInventory( mechList );
	prevInventory.Clear();

	LogisticsMech* pSelMech = 0;

	oldCBillsAmount = LogisticsData::instance->getCBills();


	for ( EList< LogisticsMech*, LogisticsMech* >::EIterator iter = mechList.Begin();
		!iter.IsDone(); iter++ )
		{
			if ( (*iter)->getForceGroup() )
				continue;
		
			prevInventory.Append( *(*iter) );
			
	
			bool bFound = 0;

			for ( int i = 0; i < inventoryListBox.GetItemCount(); i++ )
			{
				if ( ((MechListBoxItem*)inventoryListBox.GetItem(i))->getMech()->getVariant()
					== (*iter)->getVariant() )
					bFound = true;
			}

			if ( !bFound )
			{
				MechListBoxItem* item = new MechListBoxItem( (*iter), 1 );
				inventoryListBox.AddItem( item );	

			}

		}

	MechListBoxItem* item = (MechListBoxItem*)inventoryListBox.GetItem( 0 );
	if ( item )
	{
		inventoryListBox.SelectItem( 0 );
		pSelMech = item->getMech();
	}
	

	LogisticsVariant* pVariants[256];
	int count = 256;

	LogisticsData::instance->getPurchasableMechs( pVariants, count );

	for ( int i =0; i < count; i++ )
	{
		if ( !MPlayer || MPlayer->missionSettings.variants || pVariants[i]->isDesignerMech() )
		{
			LogisticsMech* pMech = new LogisticsMech( pVariants[i], -1 );
			MechListBoxItem* item = new MechListBoxItem( pMech, 1 );
			variantListBox.AddItem( item );
		}
	}

	if ( !pSelMech )
	{
		MechListBoxItem* item = (MechListBoxItem*)variantListBox.GetItem( 0 );
		if ( item )
		{
			variantListBox.SelectItem( 0 );
			pSelMech = item->getMech();
		}
	}

	status = RUNNING;
	acceptPressed = 0;

	inventoryListBox.drawCBills(1);
	variantListBox.drawCBills(1);
	variantListBox.setOrange( 0 );
	inventoryListBox.setOrange( 1 );
	
	
	setMech( pSelMech );

	pDragMech = NULL;

}
//-------------------------------------------------------------------------------------------------

void MechPurchaseScreen::end()
{
	if ( !acceptPressed && status != MAINMENU )
	{ 
		// sell all current stuff
		EList< LogisticsMech*, LogisticsMech* > list;
		LogisticsData::instance->getInventory( list );
		for ( EList< LogisticsMech*, LogisticsMech* >::EIterator iter = list.End(); !iter.IsDone(); iter-- )
		{
			LogisticsData::instance->sellMech( (*iter) );
		}


		unsigned long base, color1, color2;
		for ( MECH_LIST::EIterator pIter = prevInventory.Begin(); !pIter.IsDone(); pIter++ )
		{
			(*pIter).getColors(base, color1, color2);
			LogisticsData::instance->addMechToInventory( (*pIter).getVariant(), (*pIter).getPilot(),
				(*pIter).getForceGroup(), true );
		}

	}

	variantListBox.removeAllItems(true);
	inventoryListBox.removeAllItems(true);

	mechDisplay.setMech( NULL );
}

//-------------------------------------------------------------------------------------------------

void MechPurchaseScreen::setMech( LogisticsMech* pMech, bool FromLB )
{
	if ( status == RUNNING )
	{
		if ( FromLB ) // clicked on a disabled item
		{
			if ( !flashTime )
				flashTime = .000001f;
		}
		
		if ( FromLB ) // clicked on a disabled item
		{
			inventoryListBox.SelectItem( -1 );
			variantListBox.SelectItem( -1 );

		}
		mechDisplay.setMech( pMech );		

	}
}

//-------------------------------------------------------------------------------------------------

void MechPurchaseScreen::beginDrag( LogisticsMech* pMech )
{
	if ( status != RUNNING )
		return;
	
	if ( !pDragMech )
	{
		pDragMech = pMech;
	}

	MechListBox::initIcon( pMech, dragIcon );

	if ( inventoryListBox.pointInside( userInput->getMouseDragX(),
		userInput->getMouseDragY() ) )
	{
		dragStartLeft = true;
		inventoryListBox.dimItem( pMech, true );
	}
	else 
	{
		dragStartLeft = false;
		variantListBox.dimItem( pMech, true );
	}
}

void MechPurchaseScreen::endDrag( )
{
	if ( pDragMech )
	{
	
		if ( inventoryListBox.pointInside( userInput->getMouseX(),
			userInput->getMouseY() ) )
		{
			if ( !dragStartLeft )
			{
				addMech( pDragMech );
			}
		}
		else
		{
			if ( dragStartLeft )
				removeMech( pDragMech );
		}
	}

	inventoryListBox.undimAll();
	variantListBox.undimAll();

	pDragMech = NULL;
}


//-------------------------------------------------------------------------------------------------

int	MechPurchaseScreen::handleMessage( unsigned long what, unsigned long who )
{
	if ( status == RUNNING )
	{
		switch (who)
		{
			case MB_MSG_ADD:
				if ( INVENTORY_ID == what )
				{
					int index = inventoryListBox.GetSelectedItem();
					if ( index != -1 )
					{
						aListItem* pItem = inventoryListBox.GetItem( index );
						if ( pItem )
						{
							LogisticsMech* pMech = ((MechListBoxItem*)pItem)->getMech();
							int oldCount = LogisticsData::instance->getVariantsInInventory( pMech->getVariant(), true );
							if ( NO_ERR == LogisticsData::instance->sellMech( pMech ) && ( oldCount < 2 ) )
								((MechListBoxItem*)pItem)->resetMech( );
							soundSystem->playDigitalSample( LOG_SELECT );		
						}                                    
					}
				}

				else
					addSelectedMech();
					soundSystem->playDigitalSample( LOG_SELECT );		
				break;
			case MB_MSG_REMOVE:
				removeSelectedMech();
				break;
			case MB_MSG_NEXT:
				acceptPressed = true;
				status = DOWN;
				break;
			case MB_MSG_PREV:
				status = DOWN;
				break;
			case MB_MSG_MAINMENU:
				status = MAINMENU;
				break;
		}
	}

	return 0;

}

//-------------------------------------------------------------------------------------------------

void MechPurchaseScreen::addSelectedMech()
{
	LogisticsMech* pMech = variantListBox.getCurrentMech();
	if ( pMech )
	{
		addMech( pMech );
	}

	variantListBox.disableItemsThatCostMoreThanRP();
	int curSel = variantListBox.GetSelectedItem();
	if ( curSel == -1 )
	{
		variantListBox.SelectItem( -1 );
		inventoryListBox.SelectItem( 0 );
	}

}

void MechPurchaseScreen::addMech( LogisticsMech* pMech )
{
	LogisticsData::instance->purchaseMech( pMech->getVariant() );

		for ( int i = 0; i < inventoryListBox.GetItemCount(); i++ )
		{
			if ( ((MechListBoxItem*)inventoryListBox.GetItem(i))->getMech()->getVariant()
				== pMech->getVariant() )
			{
				return;
			}
		}

		MechListBoxItem* pItem = new MechListBoxItem( pMech, 1 );
		inventoryListBox.AddItem( pItem );
}

//-------------------------------------------------------------------------------------------------

void MechPurchaseScreen::removeSelectedMech()
{
	LogisticsMech* pMech = inventoryListBox.getCurrentMech();
	if ( pMech )
	{
		removeMech( pMech );
	}
}

void MechPurchaseScreen::removeMech( LogisticsMech* pMech )
{
	int index = inventoryListBox.GetSelectedItem();
	aListItem* pItem = inventoryListBox.GetItem( index );

	int oldCount = LogisticsData::instance->getVariantsInInventory( pMech->getVariant(), true );
	if ( NO_ERR == LogisticsData::instance->sellMech( pMech ) && ( oldCount < 2 ) )
	{
		inventoryListBox.RemoveItem( pItem, true );
	}

	if ( !inventoryListBox.GetItemCount() )
	{
		selectFirstBuyableMech();
	}
	else if ( -1 == inventoryListBox.GetSelectedItem() )
		inventoryListBox.SelectItem( 0 );

}

bool MechPurchaseScreen::selectFirstBuyableMech()
{
	for ( int i = 0; i < variantListBox.GetItemCount(); i++ )
	{
		if ( NO_ERR == LogisticsData::instance->canPurchaseMech( 
			((MechListBoxItem*)variantListBox.GetItem(i))->getMech()->getVariant() ) )
		{
			variantListBox.SelectItem( i );
			return true;
		}
	}

	return false;
}




//*************************************************************************************************
// end of file ( MechPurchaseScreen.cpp )
